# encoding:utf-8
'''
@author: adog
web: http://www.adog.net.cn
Created on 2020-11-24-
'''
#import sys 

from pymongo import MongoClient
import pandas as pd
import numpy as np
import xconfig as xcfg
import util.xtool as xtool                                                                                                                                                                                                                                           
from progressbar import Bar, Percentage, ProgressBar

host=xcfg.host
port=xcfg.mongoDB_port
username=xcfg.mdb_user
password=xcfg.mdb_pwd
dbname=xcfg.mdb_name

def col(tableName, verbose=False): 
    conn = None
    col = []
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        collect = db.get_collection(tableName)
        col = collect.find_one().keys()
        if verbose:
            print('%s: %s' % (tableName, col))
        return col
    except Exception as e:
        print(e)        
        
    finally:
        if conn is not None:
            conn.close()
        conn = None 

        
def getCollectionStatistics(dbName=None, verbose=False): 
    conn = None
    
    info = []
    if dbName is not None:
        dbname = dbName
        
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        collection_names = db.collection_names()
        for cn in collection_names:
            count = db.get_collection(cn).count()
            info.append((str(cn), count))
        df = pd.DataFrame(info, columns=['tableName', 'count'])   
        df.sort_values(['count'], ascending=[0], inplace=True)
        if verbose:
            print(df)
    except Exception as e:
        print(e)        
        
    finally:
        if conn is not None:
            conn.close()
        conn = None 
        
'''
#need to handle duplicated, so pending....

def createIndex(tableName,cIndexDict=None,verbose=False): 
    conn=None
    if cIndexDict is None:
        if verbose:
            print('Wrong: tableName createIndex without cIndexDict?')
        
    else:
        try:
            conn = MongoClient(host, port, username=username, password=password)
            dbname=C.modb_name
            db = conn.get_database(dbname)
            db.get_collection(tableName).create_index(cIndexDict)
            if verbose:
                print('%s create index: %s'%(tableName,cIndexDict))
        except Exception as e:
            print(e)        
            
        finally:
            if conn is not None:
                conn.close()
            conn=None 
'''  


def saveBatch(tableName, listOfDict, verbose=False): 
    conn = None
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        
        set = db.get_collection(tableName)  # 使用test_set集合，没有则自动创建  
        
        for di in range(len(listOfDict)):
            if verbose:
                print('%i/%i' % (di, len(listOfDict)))
            set.save(listOfDict[di])   
        print('%s to mongo(%s:%s) ok at %s' % (tableName, host, port, xtool.nowTime()))  
    except Exception as e:
        print(e)        
        
    finally:
        if conn is not None:
            conn.close()
        # conn=None 


def saveOne(tableName, dict, isLog=False): 
    if tableName is not None:
        conn = None
        try:
            conn = MongoClient(host, port, username=username, password=password)
            db = conn.get_database(dbname)
            
            set = db.get_collection(tableName)  # 使用test_set集合，没有则自动创建  
            set.save(dict)   
            if isLog:
                print('%s ok at:%s' % (tableName, xtool.nowTime()))  
        except Exception as e:
            print(e)        
            
        finally:
            if conn is not None:
                conn.close()
            conn = None 


def saveFromCsvFile(tableName, csvFileName): 
    import io
    conn = None
    file = None
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        
        set = db.get_collection(tableName)  # 使用test_set集合，没有则自动创建  
        
        # file = io.open(csvFileName,'r',encoding = 'utf-8')
        file = io.open(csvFileName, 'r', encoding='gbk')
        lines = file.readlines()
        data = [line.encode('utf-8').replace('\n', '').split(',') for line in lines]
                   
        df = pd.DataFrame(data[1:], columns=data[0])
        dfDictList = df.to_dict('record')
        pbar = ProgressBar(widgets=[Percentage(), Bar(right='|saveFromCsvFile')], maxval=len(dfDictList) + 1).start()
        for i in range(len(dfDictList)):
            set.save(dfDictList[i])   
            pbar.update(i + 1)
        pbar.finish()    
        print('%s ok at:%s' % (tableName, xtool.nowTime()))  
    except Exception as e:
        print(e)        
        
    finally:
        if conn is not None:
            conn.close()
        conn = None 
        
        if file is not None:
            file.close()
        file = None


def insert(tableName, listOfdict): 
    conn = None
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        
        set = db.get_collection(tableName)  # 使用test_set集合，没有则自动创建  
        set.insert(listOfdict)   
        print('%s ok at:%s' % (tableName, xtool.nowTime()))  
    except Exception as e:
        print(e)        
        
    finally:
        if conn is not None:
            conn.close()
        conn = None 


def find(tableName,
         queryDict=None,
         sortListOfTuple=None,  # sort: 1-acending -1 descending
         outType='list'):  # outType: 'list' (mean 'list of Dict') or 'pandas'
    conn = None
    out = None
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        collect = db.get_collection(tableName)
        res = None
        # collect.find().sort([('date', -1)])
        if queryDict is None:
            if sortListOfTuple is None:
                res = collect.find()
            else:
                res = collect.find().sort(sortListOfTuple)
        else:
            if sortListOfTuple is None:
                res = collect.find(queryDict)
            else:
                res = collect.find(queryDict).sort(sortListOfTuple)
        if outType == 'pandas':
            out = pd.DataFrame(list(res))
        elif outType == 'list':
            out = list(res)
    except Exception as e:
        print(e)        
    finally:
        if conn is not None:
            conn.close()
        # conn=None 
    return out


def updateMany(tableName, queryDict=None, setDict=None):      
    conn = None
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        collect = db.get_collection(tableName)
        res = None
        if queryDict is None:
            print('no update query condition found')
            return None
        else:
            res = collect.update_many(queryDict, setDict)
        resDict = dict(res.raw_result)
    except Exception as e:
        print(e)        
        
    finally:
        if conn is not None:
            conn.close()
        conn = None 
    return resDict


def remove(tableName, queryDict=None):   
    conn = None
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        collect = db.get_collection(tableName)
        res = None
        if queryDict is None or queryDict == 'all':
            res = collect.remove()
            print('remove all')

        else:
            res = collect.remove(queryDict)
        # return res
    except Exception as e:
        print(e)        
        
    finally:
        if conn is not None:
            conn.close()
        conn = None 

 
def aggregate(tableName,
              cols=None,
              groupBy=None,
              queryDict=None,
              sortBy=None,
              outType='list'):     
    conn = None
    out = None
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        collect = db.get_collection(tableName)
        
        res = collect.aggregate([
                               {'$match':queryDict},
                               {'$group':groupBy},
                               {'$sort':sortBy}
                               ])
        
        if outType == 'pandas':
            out = pd.DataFrame(list(res))
        elif outType == 'list':
            out = list(res)
        elif outType == 'numpy':
            out = np.array(list(res))
    except Exception as e:
        print(e)        
    finally:
        if conn is not None:
            conn.close()
        conn = None 
    return out
       
   
def listCollectsNames():   
    conn = None
    collection_names = None
    try:
        conn = MongoClient(host, port, username=username, password=password)
        db = conn.get_database(dbname)
        collection_names = db.collection_names()
        
    except Exception as e:
        print(e)        
        
    finally:
        if conn is not None:
            conn.close()
        conn = None 
    return collection_names 


if __name__ == '__main__':
   print(1)
